package UI;

import Service.PriceDataCompare;
import java.lang.reflect.Array;
import java.util.*;

import facecat.topin.core.*;
import facecat.topin.div.FCDiv;
import java.io.*;
import java.net.*;

public class PyrometerDiv extends FCDiv {
    /*
    * 数据
    */
    private ArrayList<Double> m_rates = new ArrayList<Double>();

    /*
    * 秒表计数
    */
    private int m_tick = 0;

    /*
    * 数据
    */
    private ArrayList<PriceData2> m_datas = new ArrayList<PriceData2>();

    /*
    * 秒表方法
    */
    private int m_timerID = FCView.getNewTimerID();

    public boolean m_useAnimation;

    /*
    * 添加方法
    */
    public void onAdd()
    {
        super.onAdd();
        startTimer(m_timerID, 10);
        if(m_datas.size() == 0){
             try{
                String url = "http://110.42.188.197:9968/quote?func=price&count=100&codes=all";
                URL obj = new URL(url);
                HttpURLConnection con = (HttpURLConnection) obj.openConnection();
                con.setRequestMethod("GET");
                BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
                ArrayList<String> strs = new ArrayList<String>();
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    strs.add(inputLine);
                }
                in.close();
                for (int i = 0; i < strs.size(); i++)
                {
                    String[] subStrs = strs.get(i).split("[,]");
                    if (subStrs.length >= 15)
                    {
                        PriceData2 priceData = new PriceData2();
                        priceData.m_key = subStrs[0];
                        priceData.m_text = subStrs[1];
                        priceData.m_value = FCTran.strToDouble(subStrs[6]);
                        priceData.m_close = FCTran.strToDouble(subStrs[2]);
                        priceData.m_lastClose = FCTran.strToDouble(subStrs[8]);
                        m_datas.add(priceData);
                    }
                }
                updatePyromoter();
            }catch(Exception ex){
                
            }
        }
    }

    /*
    * 移除方法
    */
    public void onRemove()
    {
        super.onRemove();
        stopTimer(m_timerID);
    }

    /*
    * 秒表方法
    */
    public void onTimer(int timerID)
    {
        super.onTimer(timerID);
        if (timerID == m_timerID)
        {
            m_tick++;
            if (m_tick > 1000000)
            {
                m_tick = 0;
            }
            boolean paint2 = false;
            if (m_useAnimation) {
                for (int i = 0; i < rects.size() && i < m_datas.size(); i++) {
                    FCRectF targetRect = rects.get(i).clone();
                    PriceData2 priceData = m_datas.get(i);
                    FCRectF nowRect = priceData.m_nowRect;
                    if (true) {
                        if (nowRect.left > targetRect.left) {
                            nowRect.left -= (nowRect.left - targetRect.left) / 4;
                            if (nowRect.left - targetRect.left < 10) {
                                nowRect.left = targetRect.left;
                            }
                            paint2 = true;
                        } else if (nowRect.left < targetRect.left) {
                            nowRect.left += (targetRect.left - nowRect.left) / 4;
                            if (targetRect.left - nowRect.left < 10) {
                                nowRect.left = targetRect.left;
                            }
                            paint2 = true;
                        }
                    }

                    if (true) {
                        if (nowRect.top > targetRect.top) {
                            nowRect.top -= (nowRect.top - targetRect.top) / 4;
                            if (nowRect.top - targetRect.top < 10) {
                                nowRect.top = targetRect.top;
                            }
                            paint2 = true;
                        } else if (nowRect.top < targetRect.top) {
                            nowRect.top += (targetRect.top - nowRect.top) / 4;
                            if (targetRect.top - nowRect.top < 10) {
                                nowRect.top = targetRect.top;
                            }
                            paint2 = true;
                        }
                    }

                    if (true) {
                        if (nowRect.right > targetRect.right) {
                            nowRect.right -= (nowRect.right - targetRect.right) / 4;
                            if (nowRect.right - targetRect.right < 10) {
                                nowRect.right = targetRect.right;
                            }
                            paint2 = true;
                        } else if (nowRect.right < targetRect.right) {
                            nowRect.right += (targetRect.right - nowRect.right) / 4;
                            if (targetRect.right - nowRect.right < 10) {
                                nowRect.right = targetRect.right;
                            }
                            paint2 = true;
                        }
                    }
                    if (true) {
                        if (nowRect.bottom > targetRect.bottom) {
                            nowRect.bottom -= (nowRect.bottom - targetRect.bottom) / 4;
                            if (nowRect.bottom - targetRect.bottom < 10) {
                                nowRect.bottom = targetRect.bottom;
                            }
                            paint2 = true;
                        } else if (nowRect.bottom < targetRect.bottom) {
                            nowRect.bottom += (targetRect.bottom - nowRect.bottom) / 4;
                            if (targetRect.bottom - nowRect.bottom < 10) {
                                nowRect.bottom = targetRect.bottom;
                            }
                            paint2 = true;
                        }
                    }
                    priceData.m_nowRect = nowRect;
                }
            }
            if (paint2)
            {
                invalidate();
            }
        }
    }

    /*
    * 重绘方法
    */
    public void onPaint(FCPaint paint, FCRect clipRect)
    {
        super.onPaint(paint, clipRect);
        int width = getWidth(), height = getHeight();
        if (m_rates.size() > 0)
        {
            for (int i = 0; i < rects.size() && i < m_datas.size(); i++)
            {
                PriceData2 pData = m_datas.get(i);
                if (pData == null)
                {
                    continue;
                }
                FCRectF rect = pData.m_nowRect;// new FCRect(rects[i].left, rects[i].top, rects[i].right, rects[i].bottom);
                if (!m_useAnimation)
                {
                    rect = new FCRectF(rects.get(i).left, rects.get(i).top, rects.get(i).right, rects.get(i).bottom);
                }
                long backColor = FCColor.None;
                long borderColor = FCColor.None;
                if (MyColor.getStyle() == 0)
                {
                    if (pData.m_close >= pData.m_lastClose)
                    {
                        backColor = FCColor.rgb(219, 68, 83);
                    }
                    else
                    {
                        backColor = FCColor.rgb(15, 193, 118);
                    }
                    borderColor = FCColor.rgb(100, 100, 100);
                }
                else
                {
                    if (pData.m_close >= pData.m_lastClose)
                    {
                        backColor = FCColor.rgb(255, 255, 255);
                    }
                    else
                    {
                        backColor = FCColor.rgb(255, 255, 255);
                        borderColor = FCColor.rgb(255, 255, 255);
                    }
                }
                FCPoint location = new FCPoint(rect.left, rect.top);
                FCSize size = new FCSize((int)(rect.right - rect.left), (int)(rect.bottom - rect.top));
                paint.fillRect(backColor, location.x, location.y, location.x + size.cx, location.y + size.cy);
                paint.drawRect(borderColor, 1, 0, location.x, location.y, location.x + size.cx, location.y + size.cy);
                int fontSize1 = (int)(Math.min(size.cx, size.cy) / 5);
                if (fontSize1 > 1)
                {
                    String baseUpper = pData.m_text;
                    FCFont font1 = new FCFont("Default", fontSize1);
                    FCSize tSize = paint.textSize(baseUpper, font1);
                    boolean isContinue = false;
                    while (tSize.cx > size.cx - 10)
                    {
                        fontSize1 = fontSize1 - 1;
                        if (fontSize1 < 1)
                        {
                            isContinue = true;
                            break;
                        }
                        font1 = new FCFont("Default", fontSize1);
                        tSize = paint.textSize(baseUpper, font1);
                    }
                    if (isContinue)
                    {
                        continue;
                    }
                    String quoteUpper = pData.m_key;
                    FCFont font2 = new FCFont("Default", fontSize1 / 2);
                    FCSize tSize2 = paint.textSize(quoteUpper, font2);
                    if (MyColor.getStyle() == 0)
                    {
                        FCDraw.drawText(paint, baseUpper, FCColor.rgb(255, 255, 255), font1, location.x + (size.cx - tSize.cx) / 2, location.y + size.cy / 2 - tSize.cy - tSize.cy / 2);
                        FCDraw.drawText(paint, quoteUpper, FCColor.rgb(255, 255, 255), font2, location.x + (size.cx - tSize2.cx) / 2, location.y + size.cy / 2 - tSize.cy / 4);
                    }
                    else
                    {
                        FCDraw.drawText(paint, baseUpper, FCColor.rgb(0, 0, 0), font1, location.x + (size.cx - tSize.cx) / 2, location.y + size.cy / 2 - tSize.cy - tSize.cy / 2);
                        FCDraw.drawText(paint, quoteUpper, FCColor.rgb(0, 0, 0), font2, location.x + (size.cx - tSize2.cx) / 2, location.y + size.cy / 2 - tSize.cy / 4);
                    }
                    String strPrice = "0.00%";
                    if(pData.m_lastClose > 0){
                        strPrice = FCTran.getValueByDigit(100 * (pData.m_close - pData.m_lastClose) / pData.m_lastClose, 2) + "%";
                        if(pData.m_close > pData.m_lastClose){
                            strPrice = "+" + strPrice;
                        }
                    }
                    FCFont font3 = new FCFont("Default", fontSize1 * 2 / 3);
                    FCSize tSize5 = paint.textSize(strPrice, font3);
                    if (MyColor.getStyle() == 0)
                    {
                        FCDraw.drawText(paint, strPrice, FCColor.rgb(255, 255, 255), font3, location.x + (size.cx - tSize5.cx) / 2, location.y + size.cy / 2 + tSize.cy - tSize.cy / 2);
                    }
                    else
                    {
                        FCDraw.drawText(paint, strPrice, FCColor.rgb(0, 0, 0), font3, location.x + (size.cx - tSize5.cx) / 2, location.y + size.cy / 2 + tSize.cy - tSize.cy / 2);
                    }
                }
            }
        }
    }
    
    public void updatePyromoter(){
        m_rates.clear();
        Collections.sort(m_datas, new PriceDataCompare());
        double totalAmount = 0;
        for (int i = 0; i < m_datas.size(); i++)
        {
            totalAmount += m_datas.get(i).m_value;
        }
        for (int i = 0; i < m_datas.size(); i++)
        {
            m_rates.add(m_datas.get(i).m_value / totalAmount);
        }
        rects.clear();
        Rwidth = WIDTH();
        Rheight = HEIGHT();
        ArrayList<Double> areas = new ArrayList<Double>();
        for (int i = 0; i < m_rates.size(); i++)
        {
            areas.add(m_rates.get(i) * WIDTH() * HEIGHT());
        }
        ArrayList<Double> children = areas;
        ArrayList<Double> row = new ArrayList<Double>();
        double w = Math.min(Rwidth, Rheight);
        while (true)
        {
            if (w <= 0) break;
            if (children.size() == 0)
            {
                if (row.size() > 0)
                {
                    layoutrow(row, w);  
                }
                break;
            }
            double c = children.get(0);
            if (c == 0)
            {
                layoutrow(row, w);
                break;
            }
            ArrayList<Double> newrow = new ArrayList<Double>();  
            for(int r = 0; r < row.size(); r++){
                newrow.add(row.get(r));
            }
            newrow.add(c);

            if (worst(row, w) >= worst(newrow, w))
            {  
                ArrayList<Double> tmp = new ArrayList<Double>();
                for (int x = 1; x < children.size(); x++)
                {
                    tmp.add(children.get(x));
                }
                children = tmp;
                row = newrow;
            }
            else
            { 
                layoutrow(row, w);  
                row = new ArrayList<Double>();
                w = width(row, (int)w);
            }
        }
    }

    public void onSizeChanged(){
        updatePyromoter();
        super.onSizeChanged();
    }

    private double INF = 0x3f3f3f;

    private int _WIDTH()
    {
        return getWidth();
    }

    private int _HEIGHT()
    {
        return getHeight();
    }

    private int WIDTH()
    {
        return getWidth();
    }

    private int HEIGHT()
    {
        return getHeight();
    }

    private ArrayList<FCRectF> rects = new ArrayList<FCRectF>();

    private double Rwidth = 0;

    private double Rheight = 0;

    public void layoutrow(List<Double> R, double w)
    {
        double lx = WIDTH() - Rwidth + (_WIDTH() - WIDTH()) / 2.0;
        double ly = HEIGHT() - Rheight + (_HEIGHT() - HEIGHT()) / 2.0;  

        int direction;  // 0: horizontal;  1: vertical

        double sum = 0;
        for (double r : R)
        {
            sum += r;
        }
        double ext = sum / w;
        if (Math.abs(w - Rwidth) <= 1e-6)
        {
            Rheight -= ext;
            direction = 0;
        }
        else
        {
            Rwidth -= ext;
            direction = 1;
        }

        for (double r : R)
        {
            if (direction == 0)
            {
                double hh = ext, ww = r / ext;
                rects.add(new FCRectF(
                        (float)Math.floor(lx), (float)Math.floor(ly), (float)Math.ceil(lx + ww), (float)Math.ceil(ly + hh)
                ));
                lx += ww;
            }
            else
            {
                double ww = ext, hh = r / ext;
                rects.add(new FCRectF(
                        (float)Math.floor(lx), (float)Math.floor(ly), (float)Math.ceil(lx + ww), (float)Math.ceil(ly + hh)
                ));
                ly += hh;
            }
        }
    }

    double width(List<Double> R, int w)
    {
        return Math.min(Rwidth, Rheight);
    }

    double worst(List<Double> R, double w)
    {
        if (R.size() == 0) return INF;
        double rmx = 0, rmn = INF, s = 0;
        for (double r : R)
        {
            s += r;
            if (r > rmx) rmx = r;
            if (r < rmn) rmn = r;
        }
        double pw = Math.pow(w, 2), sw = Math.pow(s, 2);
        double res = Math.max(pw * rmx / sw, sw / (pw * rmn));
        return Math.max(pw * rmx / sw, sw / (pw * rmn));
    }
}
